﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Thallo.Configuration;

namespace Thallo {
    static class ParameterParserFactory {

        static ParameterParserFactory() {

            Initiate();
        }

        public static Dictionary<RuntimeTypeHandle, IParameterParser> IdentityKeyParseres { get { return _cache; } }

        static Dictionary<RuntimeTypeHandle, IParameterParser> _cache = new Dictionary<RuntimeTypeHandle, IParameterParser>();
        static void Initiate() {
            var parseres = ThalloSection.Current.Assemblies.Cast<AssemblyElement>()
                                .SelectMany(a => a.KeyParseres.Cast<ParameterParserElement>())
                                .Where(k => !string.IsNullOrEmpty(k.Type))
                                .ToDictionary(k => k.Name, k => Activator.CreateInstance(Type.GetType(k.Type)) as IParameterParser);

            _cache = ThalloSection.Current.Assemblies.Cast<AssemblyElement>()
                            .SelectMany(a => a.Parameters.Cast<Parameter>())
                            .ToDictionary(k => Type.GetType(k.Type).TypeHandle, v => parseres[v.Parsor]);
        }
        
        public static IParameterParser GetParser(System.Reflection.MethodBase mi, int paramIndex) {
            var @params = mi.GetParameters();
            if (@params.Length == 0)
                return new DefaultParameterParser(null);
            var paramType = @params[paramIndex].ParameterType;
            IParameterParser parser = null;

            _cache.TryGetValue(paramType.TypeHandle, out parser);
            var defaultValue = paramType.GetHashCode().ToString();
            if (parser == null) {
                Loger.TraceInformation("Thallo\tcan not find parser of \t{0}", paramType.Name);
                return new DefaultParameterParser(paramType);
            }

            parser = parser.Clone() ;
            //parser.Prefix = defaultValue;
            parser.ValueType = paramType;
            return parser;
        }

        
    }
}
